#include "CGame.h"
#include "CMainMenuState.h"
#include "CGamePlayState.h"
#include "CHero.h"
#include "CUnit.h"
#include "CResource.h"
#include "CObjectManager.h"
#include "Mail System.h"
#include "Deliverables.h"
#include "CObjGenerator.h"
#include <string>
using std::string;

CGame::CGame()
{
	m_bIsWindowed = true;
	m_nScreenHeight = 0;
	m_nScreenWidth = 0;
}
CGame::~CGame()
{

}
CGame* CGame::GetInstance()
{
	static CGame instance;
	return &instance;
}
void CGame::Init(HWND hWnd, HINSTANCE hInstance, int nScreenWidth, int nScreenHeight, bool bIsWindowed)
{
	m_bIsWindowed = bIsWindowed;
	m_nScreenHeight = nScreenHeight;
	m_nScreenWidth = nScreenWidth;

	CSGD_Direct3D::GetInstance()->InitDirect3D(hWnd, m_nScreenWidth, m_nScreenHeight, m_bIsWindowed, false);
	CSGD_TextureManager::GetInstance()->InitTextureManager(CSGD_Direct3D::GetInstance()->GetDirect3DDevice(), CSGD_Direct3D::GetInstance()->GetSprite());
	CSGD_DirectSound::GetInstance()->InitDirectSound(hWnd);
	CSGD_WaveManager::GetInstance()->InitWaveManager(hWnd, CSGD_DirectSound::GetInstance()->GetDSObject());
	CSGD_DirectInput::GetInstance()->InitDirectInput(hWnd, hInstance, DI_KEYBOARD | DI_MOUSE);
	CSGD_DirectInput::GetInstance()->AcquireAll();
	MailSystem::GetInstance()->InitMessageSystem(MessageProc);

	srand(GetTickCount());

	ChangeState(CMainMenuState::GetInstance());
}
void CGame::Shutdown()
{
	MailSystem::GetInstance()->ShutdownMailSystem();
	CSGD_DirectInput::GetInstance()->UnacquireAll();
	CSGD_DirectInput::GetInstance()->ShutdownDirectInput();
	CSGD_WaveManager::GetInstance()->ShutdownWaveManager();
	CSGD_DirectSound::GetInstance()->ShutdownDirectSound();
	CSGD_TextureManager::GetInstance()->ShutdownTextureManager();
	CSGD_Direct3D::GetInstance()->ShutdownDirect3D();
}
bool CGame::Main()
{
	m_fGameTime = (float)(GetTickCount());
	m_fDelta = (float)(m_fGameTime - m_fPreviousTime)/1000.0f;
	m_fPreviousTime = m_fGameTime;
	CSGD_DirectInput::GetInstance()->ReadDevices();

	if (CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RETURN) && (CSGD_DirectInput::GetInstance()->KeyDown(DIK_RALT) || CSGD_DirectInput::GetInstance()->KeyDown(DIK_LALT)))
	{
		if (m_bIsWindowed)
			m_bIsWindowed = false;
		else 
			m_bIsWindowed = true;
		CSGD_Direct3D::GetInstance()->ChangeDisplayParam(640, 480, m_bIsWindowed);
		CSGD_DirectInput::GetInstance()->ReadDevices();
	}
	if(m_vecState.back() == NULL)
		return false;

	if(m_vecState.back()->Input() == false)
		return false;

	MailSystem::GetInstance()->ReadMail();
	m_vecState.back()->Update(m_fDelta);
	Render();
	return true;
}
void CGame::Render()
{
	CSGD_Direct3D::GetInstance()->Clear(0,0,128);
	CSGD_Direct3D::GetInstance()->DeviceBegin();
	CSGD_Direct3D::GetInstance()->SpriteBegin();

	m_vecState.back()->Render();

	CSGD_Direct3D::GetInstance()->SpriteEnd();
	CSGD_Direct3D::GetInstance()->DeviceEnd();
	CSGD_Direct3D::GetInstance()->Present();
}
void CGame::ChangeState(IGameState *state)
{
	while(m_vecState.size())
	{
		PopState();	
	}
	PushState(state);
}	
void CGame::PopState()
{
	if(!m_vecState.empty())
	{
		m_vecState.back()->Exit();
		m_vecState.pop_back();
	}

}
void CGame::PushState(IGameState *state)
{
	m_vecState.push_back(state);
	if(m_vecState.back() != NULL)
		m_vecState.back()->Enter();
}
void CGame::ClearAllStates()
{
}
void CGame::MessageProc(CMessage *message)
{
	switch(message->GetMsgID())
	{
	case SPAWN_HERO:
		{
			CHero* pHero;
			pHero = (CHero*)ObjectGenerator<string,CBase>::GetInstance()->MakeObject("CHero");
			pHero->SetPosX(100);
			pHero->SetPosY(100);
			pHero->SetVelX(0);
			pHero->SetVelY(0);
			pHero->SetHeight(50);
			pHero->SetWidth(50);
			CObjectManager::GetInstance()->AddObject(pHero);
			pHero->Release();
			break;
		}
	case SPAWN_UNIT:
		{
			SpawnUnit* msg = (SpawnUnit*)message;
			CUnit* pUnit;
			pUnit = (CUnit*)ObjectGenerator<string,CBase>::GetInstance()->MakeObject("CUnit");
			pUnit->SetPosX((float)(rand()%CGame::GetInstance()->GetScreenWidth()));
			pUnit->SetPosY((float)(rand()%CGame::GetInstance()->GetScreenHeight()));
			pUnit->SetVelX((float)(rand()%((50 + 50) - 50)));
			pUnit->SetVelY((float)(rand()%((50 + 50) - 50)));
			pUnit->SetHeight(10);
			pUnit->SetWidth(10);
			pUnit->SetHero(msg->GetHero());
			CObjectManager::GetInstance()->AddObject(pUnit);
			pUnit->Release();
			break;
		}
	case SPAWN_RESOURCES:
		{
			SpawnResources* msg = (SpawnResources*)message;
			CResource* pResource;
			pResource = (CResource*)ObjectGenerator<string,CBase>::GetInstance()->MakeObject("CResource");
			pResource->SetPosX((float)(rand()%CGame::GetInstance()->GetScreenWidth()));
			pResource->SetPosY((float)(rand()%CGame::GetInstance()->GetScreenHeight()));
			pResource->SetWidth(10);
			pResource->SetHeight(10);
			CObjectManager::GetInstance()->AddObject(pResource);
			pResource->Release();
			break;
		}
	}
}